from flask import Flask, render_template, request
from flask_socketio import SocketIO, join_room, leave_room
import logging
import uuid
from datetime import datetime

app = Flask(__name__)
app.config['SECRET_KEY'] = '加盐值'#自己改
socketio = SocketIO(app, cors_allowed_origins="*")


rooms = {}
users = {}

logging.basicConfig(level=logging.INFO)

@app.route('/')
def index():
    return render_template('index.html')
@app.route('/mobile')
def mobile():
    return render_template('mobile.html')
@socketio.on('connect')
def handle_connect():
    logging.info(f"客户端连接: {request.sid}")

@socketio.on('disconnect')
def handle_disconnect():
    logging.info(f"客户端断开连接: {request.sid}")
    if request.sid in users:
        user_data = users.pop(request.sid)
        room_id = user_data.get('room_id')
        if room_id in rooms:
            if request.sid in rooms[room_id]['members']:
                rooms[room_id]['members'].remove(request.sid)
                if len(rooms[room_id]['members']) > 0:
                    socketio.emit('user_left', {
                        'user_id': request.sid,
                        'timestamp': datetime.now().isoformat()
                    }, room=room_id)
                if len(rooms[room_id]['members']) == 0:
                    rooms.pop(room_id)
                    logging.info(f"房间 {room_id} 已删除")

@socketio.on('join_room')
def handle_join_room(data):
    room_id = data.get('room_id')
    public_key = data.get('public_key')
    password = data.get('password', '')
    
    if not room_id:
        room_id = str(uuid.uuid4())
    users[request.sid] = {
        'public_key': public_key,
        'room_id': room_id,
        'joined_at': datetime.now().isoformat()
    }
    if room_id not in rooms:
        rooms[room_id] = {
            'password': password,
            'created_at': datetime.now().isoformat(),
            'members': [request.sid]
        }
        socketio.emit('room_created', {'room_id': room_id}, room=request.sid)
    else:
        if rooms[room_id]['password'] != password:
            socketio.emit('error', {'message': '房间密码错误'}, room=request.sid)
            users.pop(request.sid)  
            return
        
        rooms[room_id]['members'].append(request.sid)
    join_room(room_id)
    user_list = [{'sid': sid, 'public_key': users[sid]['public_key']} 
                for sid in rooms[room_id]['members']]
    
    socketio.emit('user_joined', {
        'user_id': request.sid,
        'public_key': public_key,
        'user_list': user_list,
        'timestamp': datetime.now().isoformat()
    }, room=room_id)

@socketio.on('send_message')
def handle_send_message(data):
    room_id = data.get('room_id')
    encrypted_message = data.get('encrypted_message')
    signature = data.get('signature')
    sender_id = request.sid
    
    if room_id not in rooms or sender_id not in rooms[room_id]['members']:
        socketio.emit('error', {'message': '您不在该房间内'}, room=sender_id)
        return
    import random

    #print("模拟数据篡改攻击")
    #if signature:
    #    signature = signature[:-5] + "X"*5  # 修改签名使其无效
    #    app.logger.warning(f"模拟攻击：篡改了来自 {sender_id} 的消息")
    
    socketio.emit('new_message', {
        'sender_id': sender_id,
        'encrypted_message': encrypted_message,
        'signature': signature,
        'timestamp': datetime.now().isoformat()
    }, room=room_id, skip_sid=sender_id)

if __name__ == '__main__':
    ip = '0.0.0.0'
    port = 5000
    print(f"服务器已启动于{ip}:{port}")
    socketio.run(app, host=ip, port=port, debug=False)